-- Test HTTPd. Handles GET method only...
-- "HTTP/1.0 headers may be folded onto multiple lines if each continuation line
-- begins with a space or horizontal tab. All linear whitespace, including folding,
-- has the same semantics as SP." ... or nah, screw that. Even the RFC says so.

httpd = {}
httpd.connections = {}

function createHttpUser(socket)
	local _hu = {}
	_hu.state = "waiting_request"
	_hu.requested_resource = nil
	_hu.socket = socket
	_hu.onlythingitwilleversend = "<html><title>DC++-page.</title><body>Because every DC++ client needs a webserver.</body></html>"

	_hu.OnData = function(this, data)
		for w in string.gfind(data , "([^\r\n]*)\r\n") do
			this:ProcessMessage(w)
		end
		local t1,t2,data = string.find(data , ".*\r\n(.*)")
		this.command_buffer = data
	end

	_hu.ProcessMessage = function(this, cmd)
		local args = _parseIter(cmd)

		local stt = {
			waiting_request = function()
				if args() == "GET" then
					this.requested_resource = httpd.UnEscape(args())
					-- DC():PrintDebug(this.requested_resource)
					
					if string.sub(args(), 1, 7) == "HTTP/1." then
						-- HTTP 1.x. Send full response.
						this.state = "waiting_blank"
					else
						-- HTTP 0.9. Send simple response. (No response headers.)
						this:SendFile()
					end
				else
					DC():SocketClose(this.socket)
				end
			end,
			waiting_blank = function()
				-- ignore all request headers
				if args() == nil then
					DC():SocketWrite(_hu.socket, "HTTP/1.1 200 OK\r\nContent-Length: " ..
						string.len(this.onlythingitwilleversend) .. "\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n")
					this:SendFile()
				end
			end,
		}

		stt[this.state]()
		-- status line: "HTTP/1.0 3DIGIT\r\n"
	end

	_hu.SendFile = function(this)
		this.state = "sending"
		DC():SocketWrite(this.socket, this.onlythingitwilleversend)
	end

	return _hu
end

-- Find out MIME type from extension.

function httpd.OnAccept(socket)
	httpd.connections[socket] = createHttpUser(socket)
end

function httpd.OnRead(socket, data)
	httpd.connections[socket]:OnData(data)
end

function httpd.OnWrite(socket)
	if httpd.connections[socket].state == "sending" then DC():SocketClose(socket) end
end

function httpd.OnClose(socket)
	httpd.connections[socket] = nil
end

function httpd.UnEscape(message)
	-- escape         = "%" HEX HEX
	return message
end

RegisterSocketServer(666, httpd)